from grammarLexer import GrammarLexer

class Grammar:
    def __init__(self, filename):
        lexer = GrammarLexer(open(filename).read())
        
        self.rules = {}
        
        ruleName, ruleType = lexer.next()
        while ruleType != "ruleName":
            ruleName, ruleType = lexer.next()
            
        while not lexer.done():
            rule = self.makeRule(lexer)
            self.rules[ruleName] = rule
            
            if not lexer.done():
                ruleName, ruleType = lexer.next()
            
        for name, rule in self.rules.iteritems():
            print "\n", name
            self.printRule(rule)
        
    def printRule(self, rule, indent = 0):
        for i, rulePart in enumerate(rule):
            for tok, tokType, mod in rulePart:
                if tokType == "compound":
                    print "  " * indent, "{"
                    self.printRule(tok,indent+1)
                    print "  " * indent, "}", mod
                else:
                    print "  " * indent, tokType, tok, mod
            if i < len(rule)-1:
                print "-or-"

    def makeRule(self, lexer):
        rule = []
        rulePart = []
        
        while True:
            if lexer.done() or lexer.peek()[1] == "ruleName":
                rule.append(rulePart)
                return rule
            
            tok, tokType = lexer.next()
            if tokType in ["symbol","string"]:
                rulePart.append([tok,tokType,None])
                
            elif tokType == "(":
                rulePart.append([self.makeRule(lexer),"compound",None])
                
            elif tokType == ")":
                rule.append(rulePart)
                return rule
            
            elif tokType == "|":
                rule.append(rulePart)
                rulePart = []
            
            else:
                rulePart[-1][2] = tok
                
